package com.example.workflow.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.workflow.common.R;
import com.example.workflow.dto.DeptFormDto;
import com.example.workflow.dto.EmployeeFormDto;
import com.example.workflow.entity.EmpCoefficient;
import com.example.workflow.entity.Employee;
import com.example.workflow.entity.EmployeePosition;
import com.example.workflow.entity.Position;
import com.example.workflow.entity.RegionCoefficient;
import com.example.workflow.mapper.EmployeeMapper;
import com.example.workflow.pojo.DeptIdAndNape;
import com.example.workflow.pojo.PostIdPercent;
import com.example.workflow.service.DeptService;
import com.example.workflow.service.EmpCoefficientService;
import com.example.workflow.service.EmployeePositionService;
import com.example.workflow.service.EmployeeService;
import com.example.workflow.service.PositionService;
import com.example.workflow.service.RegionCoefficientService;
import com.example.workflow.vo.EmployeeVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.stream.Collectors;

/**
* @author hrc
* @description 针对表【employee(员工)】的数据库操作Service实现
* @createDate 2024-03-27 23:29:44
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee>
    implements EmployeeService {

    private final EmployeePositionService employeePositionService;

    private final DeptService deptService;

    private final PositionService positionService;

    private final RegionCoefficientService regionCoefficientService;

    private final EmpCoefficientService empCoefficientService ;

    /**
     * 添加员工  操作  员工表  员工岗位表  员工绩效表
     */
    @Override
    public R addEmployee(EmployeeFormDto employeeFormDto) {
        //员工号不嫩重复
        String num = employeeFormDto.getNum();
        Employee one = lambdaQuery().eq(Employee::getNum, num).one();
        if (one != null) {
            return R.error("员工号重复");
        }
        Employee employee = new Employee();
        BeanUtils.copyProperties(employeeFormDto, employee);
        save(employee);
        log.info(employee.toString());

        List<PostIdPercent> postIdPercentList = employeeFormDto.getPostIdPercent();
        //岗位所对应的绩效
        Map<Long, BigDecimal> map = postIdPercentList.stream().collect(Collectors.toMap(PostIdPercent::getPostId, PostIdPercent::getPercent));
        List<Long> postIds = employeeFormDto.getPostId();
        //向员工岗位表插入数据
        long count = postIds.stream().map(postId -> {
            EmployeePosition employeePosition = new EmployeePosition();
            employeePosition.setEmpId(employee.getId());
            employeePosition.setState(1);
            employeePosition.setPositionId(postId);
            employeePosition.setPosiPercent(map.get(postId));
            employeePosition.setCreateTime(new Date());
            employeePosition.setUpdateTime(new Date());
            employeePositionService.save(employeePosition);
            return employeePosition;
        }).count();
        log.info("新增员工具有的岗位数为{}", count);
        //向员工绩效表中添加数据
        EmpCoefficient empCoefficient = new EmpCoefficient();
        empCoefficient.setEmpId(employee.getId());
        empCoefficient.setRegionCoefficientId(employeeFormDto.getRegionId());
        empCoefficient.setPositionCoefficient(employeeFormDto.getPositionCoefficient());
        if (employeeFormDto.getState() != null) {
            empCoefficient.setState(employeeFormDto.getState());
        }
        return R.success();
    }

    /** 查询员工  擦作 员工表  员工岗位表 部门表  岗位表 地域绩效表
     * id 员工id*/
    @Override
    public R getEmployeeById(List<Long> ids) {
        List<EmployeeVo>  result = new ArrayList<>();

        for (Long id : ids) {
            Employee employee = getById(id);
            if (employee == null) {
                return R.error("员工号错误");
            }
            //员工与岗位为多对多关系
            List<EmployeePosition> employeePositions = employeePositionService.lambdaQuery().eq(EmployeePosition::getPositionId, employee.getPositionId()).list();
            EmployeeVo employeeVo = new EmployeeVo();
            List<Long> postIds = new ArrayList<>();
            ArrayList<String> postNames = new ArrayList<>();
            //员工基本属性
            BeanUtils.copyProperties(employee, employeeVo);
            // 全部部门ids 全部部门名称
            ArrayList<DeptIdAndNape> deptIdAndNapes = new ArrayList<>();
            //遍历员工的全部岗位
            List<PostIdPercent> postIdPercentList = employeePositions.stream().map(employeePosition -> {
                PostIdPercent postIdPercent = new PostIdPercent();
                Long positionId = employeePosition.getPositionId();
                //查询岗位表
                Position position = positionService.getById(positionId);
                postNames.add(position.getPosition());
                postIds.add(positionId);
                postIdPercent.setPostId(positionId);
                postIdPercent.setPercent(employeePosition.getPosiPercent());

                ArrayList<Long> deptIds = new ArrayList<>();
                StringJoiner deptNames = new StringJoiner(",");
                //获取全部部门ids 全部部门名称
                deptService.getAllSuperiorDept(positionId).getData().forEach(deptId -> {
                    deptIds.add(deptId);
                    if (deptId != null) {
                        String deptName = deptService.getById(deptId).getDeptName();
                        deptNames.add(deptName);
                    }
                });
                DeptIdAndNape deptIdAndNape = new DeptIdAndNape();
                deptIdAndNape.setDeptIds(deptIds);
                deptIdAndNape.setDeptName(deptNames.toString());
                deptIdAndNapes.add(deptIdAndNape);

                //根据岗位id去岗位表查询部门id
                Long deptId = positionService.getById(positionId).getDeptId();
                //最后根据部门id去部门表查询部门名称
                DeptFormDto deptInfo = deptService.getDeptInfo(deptId);
                employeeVo.setDeptName(deptInfo.getDeptName());
                return postIdPercent;
            }).collect(Collectors.toList());


            //设置部门ids 部门名
            employeeVo.setDeptIdAndNapeList(deptIdAndNapes);
            //岗位绩效
            employeeVo.setPostIdPercent(postIdPercentList);
            //岗位id
            employeeVo.setPostId(postIds);
            //岗位名称
            employeeVo.setPostName(postNames);

            //地域名称
            Long regionCoefficientId = empCoefficientService.lambdaQuery().eq(EmpCoefficient::getEmpId, id).one().getRegionCoefficientId();
            RegionCoefficient regionCoefficient = regionCoefficientService.getById(regionCoefficientId);
            employeeVo.setRegionName(regionCoefficient.getRegion());

            result.add(employeeVo);
        }


        return R.success(result);
    }


    /** 更新员工  操作  员工表  员工岗位表  员工绩效表*/
    @Override
    public R updateEmployee(EmployeeFormDto employeeFormDto) {
        //员工号不可重复
        String num = employeeFormDto.getNum();
        Employee one = lambdaQuery().eq(Employee::getNum, num).one();
        if (one != null) {
            return R.error("员工号重复");
        }
        //更新员工基本信息
        Employee employee = new Employee();
        BeanUtils.copyProperties(employeeFormDto, employee);
        boolean  employeeUpdated = updateById(employee);
        if (!employeeUpdated) {
            R.error("员工信息更新失败");
        }

        //更改员工岗位绩效
        List<PostIdPercent> postIdPercentList = employeeFormDto.getPostIdPercent();
        postIdPercentList.forEach(postIdPercent -> {
            EmployeePosition employeePosition = new EmployeePosition();
            employeePosition.setUpdateTime(new Date());
            employeePosition.setPositionId(postIdPercent.getPostId());
            employeePosition.setPosiPercent(postIdPercent.getPercent());
            employeePosition.setEmpId(employee.getId());

            LambdaQueryWrapper<EmployeePosition> employeePositionLambdaQueryWrapper = new LambdaQueryWrapper<>();
            employeePositionLambdaQueryWrapper.eq(EmployeePosition::getEmpId, employee.getId());
            //在岗位表更新信息
            employeePositionService.update(employeePosition, employeePositionLambdaQueryWrapper);
        });

        //更改员工的地域
        EmpCoefficient empCoefficient = empCoefficientService.lambdaQuery().eq(EmpCoefficient::getEmpId, employeeFormDto.getId()).one();
        empCoefficient.setRegionCoefficientId(employeeFormDto.getRegionId());
        return R.success("员工信息更新成功");
    }

    /** 删除员工信息  操作  员工表  员工岗位表  员工绩效表
     * ids 员工id*/

    @Override
    @Transactional
    public R deleteEmployeeById(List<Long> ids) {
        //首先删除员工表中的信息
        removeBatchByIds(ids);
        ids.forEach(id -> {
            //然后删除员工岗位表的信息
            LambdaQueryWrapper<EmployeePosition> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(EmployeePosition::getEmpId, id);
            employeePositionService.remove(wrapper);
            //最后再删除员工绩效表中的信息
            LambdaQueryWrapper<EmpCoefficient> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(EmpCoefficient::getEmpId, id);
            empCoefficientService.remove(wrapper1);
        });
        return R.success("删除成功");
    }

    /** 模糊查询员工信息  操作 员工表*/
    @Override
    public R lookByLike(EmployeeFormDto employeeFormDto) {
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Employee::getNum, employeeFormDto.getNum())
                .like(Employee::getName, employeeFormDto.getName());
        Page<Employee> page = new Page<>(employeeFormDto.getPage(), employeeFormDto.getPageSize());
        page(page, wrapper);
        List<Employee> records = page.getRecords();
        if (records == null || records.isEmpty()) {
        page(page);
        }
        return R.success(page);
    }
}




